"""
    Contans Root controller, which provides methods such lodin/logout,
    loads all other controllers and so on.
"""

import glob, os

import cherrypy, turbogears
from turbogears import controllers, expose, redirect
from turbogears import identity
from turbogears.toolbox.catwalk import CatWalk

import mnemoply.controllers
from mnemoply.model import catwalk
from mnemoply.utils import my_import
from mnemoply.error_handling import error_handler
from turbogears.view import variable_providers


class Root(controllers.RootController):
    """
        Root controller. Web server starts here.
    """

    _instance = None

    def __init__(self, *args, **kw):
        controllers.RootController.__init__(self, *args, **kw)
        self.loadControllers()
        self.loadAuthManager()

    def _cp_on_error(self):
        """
            Our error handler provider. Doesn't works under testing.
        """

        if turbogears.config.get("under_testing", False):
            raise

        return error_handler(self)

    def loadAuthManager(self):
        """
            CatWalk loader.
        """

        auth_manager = CatWalk(catwalk)
        wrapped = identity.SecureObject(auth_manager, identity.has_permission('dba'))
        setattr(self, 'auth-admin', wrapped)

    def loadControllers(self):
        """
            View controller classes in special directory and load them.
        """

        controllers_dir = os.path.dirname(mnemoply.controllers.__file__)

        for controller_file in glob.glob(os.path.join(controllers_dir, "*.py")):
            controller_name = os.path.splitext(os.path.basename(controller_file))[0]
            if controller_name.startswith('_') or controller_name == "root":
                continue
            controller_module = my_import("mnemoply.controllers." + controller_name)
            if hasattr(controller_module, "exposed") and controller_module.exposed is not None:
                controller = controller_module.exposed
                if not getattr(controller, 'allow_anonymous', False):
                    controller = identity.SecureObject(controller, identity.not_anonymous())
                setattr(self, controller_name, controller)


        path = os.path.split(controllers_dir)[0]
        controllers_dir = os.path.join(path,'_renewed_controllers' )

        for controller_file in glob.glob(os.path.join(controllers_dir, "*.py")):
            controller_name = os.path.splitext(os.path.basename(controller_file))[0]
            if controller_name.startswith('_') or controller_name == "root":
                continue
            controller_module = my_import("mnemoply._renewed_controllers." + controller_name)
            controller_name = controller_name
            if hasattr(controller_module, "exposed") and controller_module.exposed is not None:
                controller = controller_module.exposed
                self.set_controller_name(controller, controller_name)
                self.add_controller(controller)
                print 'xxxxxx ', controller.controller_name
            if hasattr(controller_module, "exposed_list") and controller_module.exposed_list is not None:
                for controller in controller_module.exposed_list:
                    self.add_controller(controller)
                     
    def set_controller_name(self, controller, prep_name ):
        if not hasattr(controller, "controller_name"):
            setattr(controller, "controller_name", '')
        if not controller.controller_name:
            controller.controller_name = prep_name
        
    
    def add_controller(self, controller):
        controller_name = controller.controller_name
        if not getattr(controller, 'allow_anonymous', False):
            controller = identity.SecureObject(controller, identity.not_anonymous())
        setattr(self, controller_name, controller)
                
    @expose(template="genshi:mnemoply.templates.welcome")
    def index(self):
        """
            Default method.
        """

        if not identity.not_anonymous():
            raise redirect("/login")
        return {}



    @expose(template="genshi:mnemoply.templates.login")
    def login(self, forward_url=None, previous_url=None, *args, **kw):
        """
            Login method.
        """

        if cherrypy.request.path == '/login':
            if turbogears.config.get('autologin.on', False):
                raise redirect('/',
                    user_name=turbogears.config.get('autologin.user_name'),
                    password=turbogears.config.get('autologin.password'),
                    login='login')

        if not identity.current.anonymous \
            and identity.was_login_attempted() \
            and not identity.get_identity_errors():
            identity.current.user.set_filter_to_session()
            raise redirect(forward_url)

        forward_url=None
        previous_url= cherrypy.request.path

        if identity.was_login_attempted():
            msg=_("The credentials you supplied were not correct or "
                   "did not grant access to this resource.")
        elif identity.get_identity_errors():
            msg=_("You must provide your credentials before accessing "
                   "this resource.")
        else:
            msg=_("Please log in.")
            forward_url= cherrypy.request.headers.get("Referer", "/")
        cherrypy.response.status=403
        return dict(message=msg, previous_url=previous_url, logging_in=True,
                    original_parameters=cherrypy.request.params,
                    forward_url=forward_url)

    @expose()
    def logout(self):
        """
            Logout method.
        """

        identity.current.logout()
        raise redirect("/login")

    @expose(template="genshi:mnemoply.templates.lib.user_info")
    def user_info(self):
        """
            Render information about current user.
        """
        return {}

    @expose(template="genshi:mnemoply.templates.readrds")
    def readrds(self):
        """
            Show static page about readrds.
        """
        return {}

    @expose(template="genshi:mnemoply.templates.templates_list")
    def templates(self):
        """
            Show all templates for ReadRDS from template directory.
        """
        return dict(files=[x for x in os.listdir("files") if not x.endswith(".tag") and x != ".svn"])

    @expose(template="genshi:mnemoply.templates.errors.duplicate")
    def error_DuplicateEntry(self, e):
        """
            Error handler for duplicate error. Render duplicate template.
        """
        return dict(err_string=e[0].replace('Duplicate entry. ', ''))

    @expose(template="genshi:mnemoply.templates.errors.permission_warning")
    @expose(format="json")
    def permission_warning(self, **kw):
        """
            Render permission warning template. Also avaible in json format.
        """
        return {}

    @classmethod
    def instance(cls):
        if cls._instance is None:
            cls._instance = Root()
        return cls._instance
